--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--[[

    空手时（跑步状态下），右键发动安魂仪式：

]]--
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- 参数
    local MAX_DISTANCE = 8*4     --- 最大长矛冲刺距离
    local AOE_SPELL_RADIUS = 7      --- 安魂仪式AOE半径
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- 寻找最远可到达的点
    local function GetMaxPassablePoint(start_pt, end_pt)
        return TUNING.HUTAO_FNS:GetMaxPassablePoint(start_pt, end_pt, MAX_DISTANCE,0.2)
    end
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- 物品检查
    local function WeaponInHandChecker(inst)
        local weapon = inst.replica.combat:GetWeapon() or inst.replica.inventory:GetEquippedItem(EQUIPSLOTS.HANDS)
        if weapon == nil then
            return true
        end
        return false
    end
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- 预处理检查函数
    local function Spell_PreCheck(inst)
        if not inst.components.playercontroller:IsEnabled() then
            return false
        end
        if inst:HasTag("playerghost") then
            return false
        end
        if inst.replica.rider and inst.replica.rider:IsRiding() then
            return false
        end
        return true
    end
    local function IsRunning(inst)
        return inst.replica.hutao_com_physical_power:IsRunning() or inst.replica.hutao_com_polearm_mastery:IsRunning()
    end
    local function IsSpellCanCast(inst)
        if not WeaponInHandChecker(inst) then
            return false
        end
        if not Spell_PreCheck(inst) then
            return false
        end
        if not IsRunning(inst) then
            return false
        end
        if not (inst.replica.hutao_com_requiem_ceremony and inst.replica.hutao_com_requiem_ceremony:Test()) then
            return false
        end
        return true
    end
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- 创建指示器
    local color = Vector3(255/255,255/255,255/255)
    local function CreateIndicator(inst)
        if not (ThePlayer and inst == ThePlayer ) then
            return
        end
        local indicator = SpawnPrefab("hutao_sfx_dotted_arrow_client")
        indicator.AnimState:SetAddColour(color.x, color.y, color.z, 0)
        indicator.AnimState:SetMultColour(color.x, color.y, color.z, 1)
        indicator.AnimState:SetBloomEffectHandle("shaders/anim.ksh")
        indicator:PushEvent("Set",{
            pt = Vector3(ThePlayer.Transform:GetWorldPosition())
        })
        --- 指示器2
        local fx = SpawnPrefab("hutao_sfx_dotted_circle_client")
        fx:PushEvent("Set",{radius = AOE_SPELL_RADIUS})
        fx.Transform:SetPosition(ThePlayer.Transform:GetWorldPosition())
        fx.AnimState:SetAddColour(color.x, color.y, color.z, 0)
        fx.AnimState:SetMultColour(color.x, color.y, color.z, 1)
        fx.AnimState:SetBloomEffectHandle("shaders/anim.ksh")
        indicator:ListenForEvent("onremove",function()
            fx:Remove()
        end)
        --- 定时检查指示器
        indicator:DoPeriodicTask(FRAMES*5,function()
            if not IsSpellCanCast(inst) then
                indicator:Remove()
            end
        end)
        --- 刷新器
        TheInput:Hutao_Add_Update_Custom_Fn(indicator,function()
            if indicator.SetRotation then
                local x,y,z = ThePlayer.Transform:GetWorldPosition()
                local mouse_pt = TheInput:GetWorldPosition()
                indicator.Transform:SetPosition(x,y,z)
                local angle = -math.deg(math.atan2(mouse_pt.z - z,mouse_pt.x - x))
                indicator:SetRotation(angle)
                mouse_pt = GetMaxPassablePoint(Vector3(x,y,z),mouse_pt)
                fx.Transform:SetPosition(mouse_pt.x,0,mouse_pt.z)
            else
                indicator:Remove()
            end
        end)
        --- 鼠标监听。
        local mouse_handle = TheInput:AddMouseButtonHandler(function(button,down)
            if down and IsSpellCanCast(inst) and button == MOUSEBUTTON_RIGHT then
                inst.replica.hutao_com_rpc_event:PushEvent("hutao_event.requiem_ceremony.spike_start",TheInput:GetWorldPosition())
            end
        end)
        indicator:ListenForEvent("onremove",function()
            mouse_handle:Remove()
        end)
        --- 隐藏/显示
        if not TUNING["hutao.Config"].SPELL_SPIKE_INDICATOR then
            indicator:Hide()
            fx:Hide()
        end
        return indicator
    end
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- 突刺冲锋+伤害
    local function do_spike_assault_and_damage(inst,tarpos) -- 突刺冲锋+伤害
        -- inst.sg:GoToState("hutao_sg_spurt",{targetpos = tarpos})
        local start_pos = Vector3(inst.Transform:GetWorldPosition())
        local end_pos = Vector3(tarpos.x,0,tarpos.z)
        local end_pos = GetMaxPassablePoint(start_pos,end_pos)
        inst.sg:GoToState("hutao_sg_spurt",{targetpos = end_pos})
        -----------------------------------------------------------------------
        --- 寻找目标
            -- local targets = inst.components.hutao_com_polearm_mastery:DoSpikeLineTargetSearch(start_pos,end_pos)
        -----------------------------------------------------------------------
        --- 造成伤害
            inst.components.hutao_com_requiem_ceremony:DoAoeDamage(end_pos)
        -----------------------------------------------------------------------
        --- 台词控制器
            -- inst.components.hutao_com_dialogue:SayWithCD("hutao_com_polearm_mastery.spike",math.random(50)/10)
        -----------------------------------------------------------------------
        --- 连续突刺控制器
            if not TUNING["hutao.Config"].ALLOW_CONTINUOUS_SPIKE then -- 设置里配置是否允许连续突刺
                inst:PushEvent("hutao_event.getting_into_the_running.force_stop") -- 停止奔跑状态
            end
        -----------------------------------------------------------------------
    end
    local function Spike_start(inst,pos)
        if not IsSpellCanCast(inst) then
            return
        end
        do_spike_assault_and_damage(inst,pos)
    end
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

return function(inst)
    -------------------------------------------------------
    --- 冲刺完成后，启动长矛指示器
        local indicator_task = nil
        local function indicator_task_fn(inst)
            if IsSpellCanCast(inst) then
                    -------------------------------------
                    if inst.___requiem_ceremony_indicator and inst.___requiem_ceremony_indicator:IsValid() then

                    else
                        inst.___requiem_ceremony_indicator = CreateIndicator(inst)
                        -- print("create new indicator")
                    end
                    -------------------------------------
                end
        end
        inst:ListenForEvent("hutao_event.client_side.requiem_ceremony.spike_create_indicator",function(inst,flag)
            if not IsSpellCanCast(inst) then
                return
            end
            -- print("fake error hutao_classified_physical_power_running",flag,IsRunning(inst))
            if flag and indicator_task == nil then
                    indicator_task_fn(inst)
                    indicator_task = inst:DoPeriodicTask(0.5,indicator_task_fn)
            elseif flag == false then

                    if indicator_task then
                        indicator_task:Cancel()
                        indicator_task = nil
                    end

                    if inst.___requiem_ceremony_indicator and inst.___requiem_ceremony_indicator:IsValid() then
                        inst.___requiem_ceremony_indicator:Remove()
                        inst.___requiem_ceremony_indicator = nil
                    end

            end


        end)
    -------------------------------------------------------
    --- 双重 running 事件判定，减少net 肯能的延迟 造成 无法顺利切换到突刺。
        ----- 通过 hutao_com_physical_power net 来的事件。
        inst:ListenForEvent("hutao_classified_physical_power_running",function(inst,flag)
            -- flag = flag or inst.replica.hutao_com_requiem_ceremony:IsRunning()
            local flag = IsRunning(inst)
            inst:PushEvent("hutao_event.client_side.requiem_ceremony.spike_create_indicator",flag)
        end)
        ----- 通过 hutao_com_requiem_ceremony net 来的事件。
        inst:ListenForEvent("hutao_classified_requiem_ceremony_data",function(inst)
            local flag = IsRunning(inst)
            inst:PushEvent("hutao_event.client_side.requiem_ceremony.spike_create_indicator",flag)
        end)
    -------------------------------------------------------
    ---
        if not TheWorld.ismastersim then
            return
        end
    -------------------------------------------------------
    --- RPC 回环执行
        inst:ListenForEvent("hutao_event.requiem_ceremony.spike_start",Spike_start)
    -------------------------------------------------------
end